package org.sqlproc.sample.tutorial.model;

import java.util.Date;

import javax.persistence.AttributeOverride;
import javax.persistence.AttributeOverrides;
import javax.persistence.Column;
import javax.persistence.Embedded;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.MappedSuperclass;
import javax.persistence.Version;

import org.hibernate.annotations.Type;
import org.hibernate.validator.constraints.NotEmpty;
import org.joda.time.LocalDate;

/**
 * Generated base class, which implements properties and
 * associations for the domain object.
 * <p>Make sure that subclass defines the following annotations:
 * <pre>
@javax.persistence.Entity
@javax.persistence.Table(name = "PERSON"    , uniqueConstraints = @javax.persistence.UniqueConstraint(columnNames={"SSN_NUMBER", "SSN_COUNTRY"}))
 * </pre>
 *
 */
@MappedSuperclass
//@EntityListeners({org.hibernate.validator.event.JPAValidateListener.class,
//    org.fornax.cartridges.sculptor.framework.domain.AuditListener.class
//})
public abstract class PersonBase {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "ID")
    private Long id;
    @Column(name = "BIRTHDATE", nullable = false)
    @Type(type = "org.joda.time.contrib.hibernate.PersistentLocalDate")
    @NotEmpty
    private LocalDate birthDate;
    @Column(name = "CREATEDDATE")
    @Type(type = "timestamp")
    private Date createdDate;
    @Column(name = "CREATEDBY", length = 50)
    private String createdBy;
    @Column(name = "LASTUPDATED")
    @Type(type = "timestamp")
    private Date lastUpdated;
    @Column(name = "LASTUPDATEDBY", length = 50)
    private String lastUpdatedBy;
    @Version
    @Column(name = "VERSION")
    private Long version;
    @Column(name = "SEX", nullable = false)
    @Type(type = "Gender")
    @NotEmpty
    private Gender sex;
    @Column(name = "CLOTHES_SIZE", nullable = true)
    //@Type(type = "Size")
    @NotEmpty
    private Size clothesSize;
    @Embedded
    @AttributeOverrides({@AttributeOverride(name = "number",column = @Column(name = "SSN_NUMBER",nullable = true,length = 20)
        )
        , @AttributeOverride(name = "country",column = @Column(name = "SSN_COUNTRY",nullable = true)
        )
    })
    @NotEmpty
    private Ssn ssn;
    @Embedded
    @AttributeOverrides({@AttributeOverride(name = "first",column = @Column(name = "NAME_FIRST",nullable = true,length = 100)
        )
        , @AttributeOverride(name = "last",column = @Column(name = "NAME_LAST",nullable = true,length = 100)
        )
    })
    @NotEmpty
    private PersonName name;

    public PersonBase() {
    }

    public PersonBase(Gender sex, Ssn ssn) {
        super();
        this.sex = sex;
        this.ssn = ssn;
    }

    public Long getId() {
        return id;
    }

    /**
     * The id is not intended to be changed or assigned manually, but
     * for test purpose it is allowed to assign the id.
     */
    public void setId(Long id) {
        if ((this.id != null) && !this.id.equals(id)) {
            throw new IllegalArgumentException(
                "Not allowed to change the id property.");
        }
        this.id = id;
    }

    public LocalDate getBirthDate() {
        return birthDate;
    }

    public void setBirthDate(LocalDate birthDate) {
        this.birthDate = birthDate;
    }

    public Date getCreatedDate() {
        return createdDate;
    }

    public void setCreatedDate(Date createdDate) {
        this.createdDate = createdDate;
    }

    public String getCreatedBy() {
        return createdBy;
    }

    public void setCreatedBy(String createdBy) {
        this.createdBy = createdBy;
    }

    public Date getLastUpdated() {
        return lastUpdated;
    }

    public void setLastUpdated(Date lastUpdated) {
        this.lastUpdated = lastUpdated;
    }

    public String getLastUpdatedBy() {
        return lastUpdatedBy;
    }

    public void setLastUpdatedBy(String lastUpdatedBy) {
        this.lastUpdatedBy = lastUpdatedBy;
    }

    public Long getVersion() {
        return version;
    }

    public void setVersion(Long version) {
        this.version = version;
    }

    public Gender getSex() {
        return sex;
    }

    public void setSex(Gender sex) {
        this.sex = sex;
    }

    public Ssn getSsn() {
        return ssn;
    }

    public void setSsn(Ssn ssn) {
        this.ssn = ssn;
    }

    public PersonName getName() {
        return name;
    }

    public void setName(PersonName name) {
        this.name = name;
    }
    
    

    /**
     * This method is used by toString. It specifies what to
     * include in the toString result.
     * @return true if the field is to be included in toString
     */
//    protected boolean acceptToString(Field field) {
//        if (super.acceptToString(field)) {
//            return true;
//        } else {
//            if (field.getName().equals("ssn")) {
//                return true;
//            }
//
//            if (field.getName().equals("name")) {
//                return true;
//            }
//
//            if (field.getName().equals("sex")) {
//                return true;
//            }
//            return false;
//        }
//    }

    public Size getClothesSize() {
		return clothesSize;
	}

	public void setClothesSize(Size clothesSize) {
		this.clothesSize = clothesSize;
	}

	/**
     * This method is used by equals and hashCode.
     * @return {@link #getSsn}
     */
    public Object getKey() {
        return getSsn();
    }
}
